home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / term / term_47a_pch.lha / Source / gtlayout-38.3 / LTP_TabClass.c < prev    next >
C/C++ Source or Header  |  1996-11-02  |  18KB  |  834 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1996 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #if defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  15.  
  16. #define TIA_Labels        (TAG_USER+0x90000)
  17. #define TIA_Font        (TAG_USER+0x90001)
  18. #define TIA_Screen        (TAG_USER+0x90002)
  19. #define TIA_Index        (TAG_USER+0x90003)
  20. #define TIA_DrawInfo    (TAG_USER+0x90004)
  21. #define TIA_SizeType    (TAG_USER+0x90005)
  22.  
  23. STATIC VOID
  24. DrawCap(struct RastPort *RPort,LONG Left,LONG Top,LONG Width,LONG Height,BOOL Flip)
  25. {
  26.     LONG x,y,da,MidX,MidY,r,Full,Push,Mult;
  27.  
  28.     Full = Height;
  29.  
  30.     Height = Width;
  31.  
  32.     MidX = Left;
  33.     MidY = Top + Height - 1;
  34.  
  35.     r = Height - 1;
  36.  
  37.     x = 0;
  38.     y = r;
  39.     da = r - 1;
  40.  
  41.     if(Flip)
  42.     {
  43.         Push = Width - 1;
  44.         Mult = -1;
  45.     }
  46.     else
  47.     {
  48.         Push = 0;
  49.         Mult = 1;
  50.     }
  51.  
  52.     do
  53.     {
  54.         if(da < 0)
  55.         {
  56.             y--;
  57.  
  58.             da += y * 2;
  59.         }
  60.  
  61.         WritePixel(RPort,Left + Push + Mult * (x + MidX - Left),-y + MidY);
  62.         WritePixel(RPort,Left + Push + Mult * (y + MidX - Left),-x + MidY);
  63.  
  64.         da -= (1 + x * 2);
  65.  
  66.         x++;
  67.     }
  68.     while(x <= y);
  69.  
  70.     Left += Width - 1 - Push;
  71.  
  72. /*    This is what it used to be. Easily catches fire, take care
  73.  
  74.     if(Flip)
  75.     {
  76.         do
  77.         {
  78.             if(da < 0)
  79.             {
  80.                 y--;
  81.  
  82.                 da += y * 2;
  83.             }
  84.  
  85.             WritePixel(RPort,Left + Width - 1 - (x + MidX - Left),-y + MidY);
  86.             WritePixel(RPort,Left + Width - 1 - (y + MidX - Left),-x + MidY);
  87.  
  88.             da -= (1 + x * 2);
  89.  
  90.             x++;
  91.         }
  92.         while(x <= y);
  93.     }
  94.     else
  95.     {
  96.         do
  97.         {
  98.             if(da < 0)
  99.             {
  100.                 y--;
  101.  
  102.                 da += y * 2;
  103.             }
  104.  
  105.             WritePixel(RPort,x + MidX,-y + MidY);
  106.             WritePixel(RPort,y + MidX,-x + MidY);
  107.  
  108.             da -= (1 + x * 2);
  109.  
  110.             x++;
  111.         }
  112.         while(x <= y);
  113.  
  114.         Left += Width - 1;
  115.     }
  116. */
  117.     LTP_DrawLine(RPort,Left,Top + Height,Left,Top + Full - 1);
  118. }
  119.  
  120. STATIC VOID
  121. RenderTabs(struct RastPort *RPort,struct Gadget *gadget,TabInfo *Info,UWORD *Pens,LONG Pull)
  122. {
  123.     LONG    Width,Height;
  124.     LONG    i;
  125.     LONG    Pen;
  126.  
  127.     Width    = Info->TabWidth;
  128.     Height    = Info->TabHeight;
  129.  
  130.     SetRast(&Info->RPort,Pens[BACKGROUNDPEN]);
  131.  
  132.     for(i = 0 ; i < 4 ; i++)
  133.     {
  134.         if(i & 1)
  135.         {
  136.             if(Pens[SHINEPEN] == Pens[SHADOWPEN])
  137.                 Pen = BACKGROUNDPEN;
  138.             else
  139.                 Pen = SHADOWPEN;
  140.         }
  141.         else
  142.             Pen = SHINEPEN;
  143.  
  144.         LTP_SetAPen(&Info->RPort,Pens[Pen]);
  145.  
  146.         LTP_DrawLine(&Info->RPort,0,Height - 1 - i,gadget->Width - 1 - Info->Thick * i,Height - 1 - i);
  147.     }
  148.  
  149.     for(i = Info->Count - 1 ; i >= 0 ; i--)
  150. //    for(i = 0 ; i < Info->Count ; i++)
  151.     {
  152.         if(i != Info->Current)
  153.             BltMaskBitMapRastPort(Info->Tabs[i].BitMap,0,0,&Info->RPort,Info->Tabs[i].Left,4,Width,Height - 6,ABC|ABNC|ANBC,Info->Mask);
  154.     }
  155.  
  156.     BltMaskBitMapRastPort(Info->Tabs[Info->Current].BitMap,0,0,&Info->RPort,Info->Tabs[Info->Current].Left,0,Width,Height - Pull,ABC|ABNC|ANBC,Info->Mask);
  157.  
  158.     WaitBlit();
  159.  
  160.     BltBitMapRastPort(Info->BitMap,0,0,RPort,gadget->LeftEdge,gadget->TopEdge + gadget->Height - (Info->TabHeight + 2),gadget->Width,Info->TabHeight,0xC0);
  161. }
  162.  
  163. STATIC VOID
  164. SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  165. {
  166.     TabInfo            *Info = INST_DATA(class,gadget);
  167.     struct TagItem    *Tag;
  168.     BOOL             NeedRefresh = FALSE;
  169.     BOOL             Disabled;
  170.  
  171.     Disabled = (BOOL)((gadget->Flags & GFLG_DISABLED) != 0);
  172.  
  173.     if(Tag = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
  174.     {
  175.         if(Tag->ti_Data && !Disabled || !Tag->ti_Data && Disabled)
  176.             NeedRefresh = TRUE;
  177.     }
  178.  
  179.     if(Tag = FindTagItem(TIA_Index,SetInfo->ops_AttrList))
  180.     {
  181.         LONG Index = Tag->ti_Data;
  182.  
  183.         if(Index >= Info->Count)
  184.             Index = Info->Count - 1;
  185.  
  186.         if(Index != Info->Current)
  187.         {
  188.             Info->Initial = Info->Current = Index;
  189.  
  190.             NeedRefresh = TRUE;
  191.         }
  192.     }
  193.  
  194.     if(NeedRefresh)
  195.     {
  196.         struct RastPort *RPort;
  197.  
  198.         if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
  199.         {
  200.             DoMethod((Object *)gadget,GM_RENDER,SetInfo->ops_GInfo,RPort,GREDRAW_REDRAW);
  201.  
  202.             ReleaseGIRPort(RPort);
  203.         }
  204.     }
  205. }
  206.  
  207. STATIC ULONG
  208. RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
  209. {
  210.     TabInfo *Info = INST_DATA(class,gadget);
  211.  
  212.     RenderTabs(RenderInfo->gpr_RPort,gadget,Info,RenderInfo->gpr_GInfo->gi_DrInfo->dri_Pens,RenderInfo->gpr_Redraw == GREDRAW_UPDATE ? 2 : 0);
  213.  
  214.     return(TRUE);
  215. }
  216.  
  217. STATIC VOID
  218. DisposeMethod(struct IClass *class,struct Gadget *gadget,Msg msg)
  219. {
  220.     TabInfo *Info = INST_DATA(class,gadget);
  221.  
  222.     if(Info->Mask || Info->Tabs || Info->BitMap)
  223.         WaitBlit();
  224.  
  225.     if(Info->Mask)
  226.     {
  227.         if(Info->ChipMask)
  228.             FreeVec(Info->Mask);
  229.         else
  230.             FreeRaster(Info->Mask,Info->TabWidth,Info->TabHeight);
  231.     }
  232.  
  233.     if(Info->Tabs)
  234.     {
  235.         LONG i;
  236.  
  237.         for(i = 0 ; i < Info->Count ; i++)
  238.             LTP_DeleteBitMap(Info->Tabs[i].BitMap,TRUE);
  239.  
  240.         FreeVec(Info->Tabs);
  241.     }
  242.  
  243.     LTP_DeleteBitMap(Info->BitMap,FALSE);
  244. }
  245.  
  246. STATIC ULONG
  247. NewMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  248. {
  249.     if(gadget = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo))
  250.     {
  251.         TabInfo            *Info = INST_DATA(class,gadget);
  252.         struct TagItem    *Tag,*TagList = SetInfo->ops_AttrList;
  253.         struct TextAttr    *FontAttr;
  254.         LONG             Width,Height;
  255.         struct DrawInfo    *DrawInfo;
  256.         STRPTR            *Labels;
  257.         struct Screen    *Screen;
  258.  
  259.         Width        = 0;
  260.         Height        = 0;
  261.  
  262.         FontAttr    = NULL;
  263.         DrawInfo    = NULL;
  264.         Labels        = NULL;
  265.         Screen        = NULL;
  266.  
  267.         memset(Info,0,sizeof(TabInfo));
  268.  
  269.         while(Tag = NextTagItem(&TagList))
  270.         {
  271.             switch(Tag->ti_Tag)
  272.             {
  273.                 case GA_Width:
  274.                     Width = Tag->ti_Data;
  275.                     break;
  276.  
  277.                 case GA_Height:
  278.                     Height = Tag->ti_Data;
  279.                     break;
  280.  
  281.                 case TIA_Labels:
  282.                     Labels = (STRPTR *)Tag->ti_Data;
  283.                     break;
  284.  
  285.                 case TIA_Font:
  286.                     FontAttr = (struct TextAttr *)Tag->ti_Data;
  287.                     break;
  288.  
  289.                 case TIA_Screen:
  290.                     Screen = (struct Screen *)Tag->ti_Data;
  291.                     break;
  292.  
  293.                 case TIA_Index:
  294.                     Info->Current = Tag->ti_Data;
  295.                     break;
  296.  
  297.                 case TIA_DrawInfo:
  298.                     DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  299.                     break;
  300.             }
  301.         }
  302.  
  303.         if(Labels)
  304.         {
  305.             while(Labels[Info->Count])
  306.                 Info->Count++;
  307.         }
  308.  
  309.         if(Screen && DrawInfo && FontAttr && Width && Height && Labels && Info->Count)
  310.         {
  311.             struct TextFont *Font;
  312.  
  313.             if(Font = OpenFont(FontAttr))
  314.             {
  315.                 struct RastPort *RPort = &Info->RPort;
  316.  
  317.                 InitRastPort(RPort);
  318.  
  319.                 SetFont(RPort,Font);
  320.  
  321.                 if(Height >= RPort->TxHeight + 11)
  322.                 {
  323.                     LONG i,Len,MaxWidth,Remain;
  324.                     LONG Lean;
  325.  
  326.                     if(Info->Current < 0)
  327.                         Info->Current = 0;
  328.                     else
  329.                     {
  330.                         if(Info->Current >= Info->Count)
  331.                             Info->Current = Info->Count - 1;
  332.                     }
  333.  
  334.                     Lean = (TextLength(RPort,"O",1) + 1) / 2;
  335.  
  336.                     Info->Thick    = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
  337.  
  338.                     if(Info->Thick < 1)
  339.                         Info->Thick = 1;
  340.  
  341.                     for(i = MaxWidth = 0 ; i < Info->Count ; i++)
  342.                     {
  343.                         if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  344.                             MaxWidth = Len;
  345.                     }
  346.  
  347.                     MaxWidth = Info->Thick + (Lean + Info->Thick - 1 + Info->Thick + MaxWidth + Info->Thick + Lean + Info->Thick - 1) + Info->Thick;
  348.  
  349.                     Remain = (Width - MaxWidth - 5 * Info->Thick) / (Info->Thick * 4);
  350.  
  351.                     if(Remain >= Info->Count - 1)
  352.                     {
  353.                         if(Info->Tabs = (TabEntry *)AllocVec(sizeof(TabEntry) * Info->Count,MEMF_ANY|MEMF_CLEAR))
  354.                         {
  355.                             STATIC BYTE PenNumbers[] =
  356.                             {
  357.                                 BACKGROUNDPEN,
  358.                                 SHINEPEN,
  359.                                 SHADOWPEN,
  360.                                 TEXTPEN
  361.                             };
  362.  
  363.                             struct BitMap     Mask;
  364.                             LONG             Depth;
  365.                             LONG             MaxPen;
  366.                             UWORD            *Pens = DrawInfo->dri_Pens;
  367.                             BOOL             GotIt = TRUE;
  368.  
  369.                             memset(&Mask,0,sizeof(Mask));
  370.  
  371.                             for(i = 0, MaxPen = -1 ; i < sizeof(PenNumbers) ; i++)
  372.                             {
  373.                                 if(Pens[PenNumbers[i]] > MaxPen)
  374.                                     MaxPen = Pens[PenNumbers[i]];
  375.                             }
  376.  
  377.                             for(i = 1 ; i < 9 ; i++)
  378.                             {
  379.                                 if(MaxPen < (1 << i))
  380.                                 {
  381.                                     Depth = i;
  382.                                     break;
  383.                                 }
  384.                             }
  385.  
  386.                             Info->TabWidth    = MaxWidth;
  387.                             Info->TabHeight    = 4 + RPort->TxHeight + 5;
  388.  
  389.                             InitBitMap(&Mask,1,Info->TabWidth,Info->TabHeight);
  390.  
  391.                             Mask.Planes[1] = NULL;
  392.  
  393.                             for(i = 0 ; GotIt && i < 2 ; i++)
  394.                             {
  395.                                 if(!(Mask.Planes[i] = (PLANEPTR)AllocRaster(Info->TabWidth,Info->TabHeight)))
  396.                                     GotIt = FALSE;
  397.                             }
  398.  
  399.                             if(GotIt)
  400.                             {
  401.                                 ULONG Type;
  402.  
  403.                                 Type = MEMF_CHIP;
  404.  
  405.                                 for(i = 0 ; i < 2 ; i++)
  406.                                     Type &= TypeOfMem(Mask.Planes[i]);
  407.  
  408.                                 if(!(Type & MEMF_CHIP))
  409.                                 {
  410.                                     LONG PageSize;
  411.  
  412.                                     for(i = 0 ; i < 2 ; i++)
  413.                                     {
  414.                                         FreeRaster(Mask.Planes[i],Info->TabWidth,Info->TabHeight);
  415.                                         Mask.Planes[i] = NULL;
  416.                                     }
  417.  
  418.                                     PageSize = Mask.BytesPerRow * Mask.Rows;
  419.  
  420.                                     for(i = 0 ; i < 2 ; i++)
  421.                                     {
  422.                                         if(!(Mask.Planes[i] = (PLANEPTR)AllocVec(PageSize,MEMF_CHIP)))
  423.                                             GotIt = FALSE;
  424.                                     }
  425.  
  426.                                     Info->ChipMask = TRUE;
  427.                                 }
  428.                             }
  429.  
  430.                             for(i = 0 ; GotIt && i < Info->Count ; i++)
  431.                             {
  432.                                 if(!(Info->Tabs[i].BitMap = LTP_CreateBitMap(Info->TabWidth,Info->TabHeight,Depth,NULL,TRUE)))
  433.                                     GotIt = FALSE;
  434.                             }
  435.  
  436.                             if(GotIt)
  437.                             {
  438.                                 Depth = LTP_GetDepth(Screen->RastPort.BitMap);
  439.  
  440.                                 if(!(Info->BitMap = LTP_CreateBitMap(gadget->Width,Info->TabHeight,Depth,Screen->RastPort.BitMap,FALSE)))
  441.                                     GotIt = FALSE;
  442.                             }
  443.  
  444.                             if(GotIt)
  445.                             {
  446.                                 struct TmpRas     TmpRas;
  447.                                 LONG             j,Len,Offset,Pos;
  448.  
  449.                                 InitTmpRas(&TmpRas,Mask.Planes[1],RASSIZE(Info->TabWidth,Info->TabHeight));
  450.  
  451.                                 RPort->TmpRas    = &TmpRas;
  452.                                 RPort->BitMap    = &Mask;
  453.  
  454.                                 SetRast(RPort,0);
  455.  
  456.                                 LTP_SetPens(RPort,1,0,JAM1);
  457.  
  458.                                 DrawCap(RPort,0,0,Lean,Info->TabHeight,TRUE);
  459.                                 LTP_DrawLine(RPort,Lean,0,Info->TabWidth - (Lean + 1),0);
  460.  
  461.                                 DrawCap(RPort,Info->TabWidth - Lean,0,Lean,Info->TabHeight,FALSE);
  462.                                 LTP_DrawLine(RPort,0,Info->TabHeight - 1,Info->TabWidth - 1,Info->TabHeight - 1);
  463.  
  464.                                 Flood(RPort,1,Info->TabWidth / 2,Info->TabHeight / 2);
  465.  
  466.                                 LTP_SetAPen(RPort,0);
  467.  
  468.                                 for(i = 0 ; i < 2 ; i++)
  469.                                 {
  470.                                     for(j = 0 ; j < Info->Thick ; j++)
  471.                                         WritePixel(RPort,j,Info->TabHeight - 1 - i);
  472.  
  473.                                     for(j = 0 ; j < Info->Thick ; j++)
  474.                                         WritePixel(RPort,Info->TabWidth - 1 - j,Info->TabHeight - 1 - i);
  475.                                 }
  476.  
  477.                                 WaitBlit();
  478.  
  479.                                 if(Info->ChipMask)
  480.                                     FreeVec(Mask.Planes[1]);
  481.                                 else
  482.                                     FreeRaster(Mask.Planes[1],Info->TabWidth,Info->TabHeight);
  483.  
  484.                                     // *VERY* important; leaving a dead TmpRas around will
  485.                                     // cause problems with Text() later as Gfx may use
  486.                                     // RPort->TmpRas for buffering.
  487.  
  488.                                 RPort->TmpRas = NULL;
  489.  
  490.                                 Offset = (Width - Info->Thick * 5) / Info->Count;
  491.  
  492.                                 while(Offset > 0 && Offset * (Info->Count - 1) + Info->TabWidth >= Width - Info->Thick * 5)
  493.                                     Offset--;
  494.  
  495.                                 if(Offset > Info->TabWidth + Info->Thick)
  496.                                     Offset = Info->TabWidth + Info->Thick;
  497.  
  498.                                 Pos = 2 * Info->Thick;
  499.  
  500.                                 for(i = 0 ; i < Info->Count ; i++)
  501.                                 {
  502.                                     RPort->BitMap = Info->Tabs[i].BitMap;
  503.  
  504.                                     Info->Tabs[i].Left = Pos;
  505.                                     Pos += Offset;
  506.  
  507.                                     SetRast(RPort,Pens[BACKGROUNDPEN]);
  508.  
  509.                                     LTP_SetAPen(RPort,Pens[SHINEPEN]);
  510.  
  511.                                     for(j = 0 ; j < Info->Thick ; j++)
  512.                                         DrawCap(RPort,Info->Thick + j,0,Lean,Info->TabHeight,TRUE);
  513.  
  514.                                     LTP_DrawLine(RPort,Info->Thick + Lean,0,Info->TabWidth - (Lean + 1) - Info->Thick,0);
  515.  
  516.                                     LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  517.  
  518.                                     for(j = 0 ; j < Info->Thick ; j++)
  519.                                         DrawCap(RPort,Info->TabWidth - Lean - j - Info->Thick,0,Lean,Info->TabHeight,FALSE);
  520.  
  521.                                     LTP_SetAPen(RPort,Pens[TEXTPEN]);
  522.                                     Len = strlen(Labels[i]);
  523.  
  524.                                     LTP_PrintText(RPort,Labels[i],Len,(Info->TabWidth - TextLength(RPort,Labels[i],Len)) / 2,2);
  525.                                 }
  526.  
  527.                                 Info->Mask = Mask.Planes[0];
  528.  
  529.                                 Info->Offset = Offset;
  530.  
  531.                                 Info->RPort.BitMap = Info->BitMap;
  532.  
  533.                                 CloseFont(Font);
  534.  
  535.                                 return((ULONG)gadget);
  536.                             }
  537.                         }
  538.                     }
  539.                 }
  540.  
  541.                 CloseFont(Font);
  542.             }
  543.         }
  544.  
  545.         CoerceMethod(class,(Object *)gadget,OM_DISPOSE);
  546.     }
  547.  
  548.     return(0);
  549. }
  550.  
  551. STATIC ULONG
  552. InputMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  553. {
  554.     TabInfo    *Info    = INST_DATA(class,gadget);
  555.     ULONG     Result    = GMR_MEACTIVE;
  556.     LONG     x,y;
  557.     BOOL     Done    = FALSE;
  558.  
  559.     x = InputInfo->gpi_Mouse.X;
  560.     y = InputInfo->gpi_Mouse.Y;
  561.  
  562.     if(InputInfo->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  563.     {
  564.         if(InputInfo->gpi_IEvent->ie_Code == MENUDOWN)
  565.         {
  566.             Result    = GMR_NOREUSE;
  567.             Done    = TRUE;
  568.         }
  569.         else
  570.         {
  571.             if(InputInfo->gpi_IEvent->ie_Code == SELECTUP)
  572.             {
  573.                 Done = TRUE;
  574.  
  575.                 if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  576.                 {
  577.                     Result = GMR_NOREUSE | GMR_VERIFY;
  578.  
  579.                     *InputInfo->gpi_Termination = Info->Current;
  580.                 }
  581.                 else
  582.                     Result = GMR_NOREUSE;
  583.             }
  584.         }
  585.     }
  586.  
  587.     if(Result == GMR_NOREUSE)
  588.     {
  589.         struct RastPort    *RPort;
  590.  
  591.         if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  592.         {
  593.             Info->Current = Info->Initial;
  594.  
  595.             DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_REDRAW);
  596.  
  597.             ReleaseGIRPort(RPort);
  598.         }
  599.     }
  600.  
  601.     if(!Done)
  602.     {
  603.         if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  604.         {
  605.             LONG Index,i;
  606.  
  607.             for(Index = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  608. //            for(Index = -1, i = 0 ; i < Info->Count ; i++)
  609.             {
  610.                 if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  611.                     Index = i;
  612.             }
  613.  
  614.             if(Index != Info->Current && Index != -1)
  615.             {
  616.                 struct RastPort    *RPort;
  617.  
  618.                 if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  619.                 {
  620.                     Info->Current = Index;
  621.  
  622.                     DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_UPDATE);
  623.  
  624.                     ReleaseGIRPort(RPort);
  625.                 }
  626.             }
  627.         }
  628.     }
  629.  
  630.     return(Result);
  631. }
  632.  
  633. STATIC ULONG
  634. ActiveMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  635. {
  636.     TabInfo            *Info = INST_DATA(class,gadget);
  637.     struct RastPort    *RPort;
  638.  
  639.     if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  640.     {
  641.         LONG Current,i;
  642.         LONG x;
  643.  
  644.         x = InputInfo->gpi_Mouse.X;
  645.  
  646.         for(Current = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  647. //        for(Current = -1, i = 0 ; i < Info->Count ; i++)
  648.         {
  649.             if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  650.                 Current = i;
  651.         }
  652.  
  653.         Info->Initial = Info->Current;
  654.  
  655.         if(Current != Info->Current && Current != -1)
  656.         {
  657.             Info->Current = Current;
  658.  
  659.             DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_UPDATE);
  660.         }
  661.  
  662.         ReleaseGIRPort(RPort);
  663.  
  664.         return(GMR_MEACTIVE);
  665.     }
  666.     else
  667.         return(GMR_NOREUSE);
  668. }
  669.  
  670. STATIC ULONG
  671. InactiveMethod(struct IClass *class,struct Gadget *gadget,struct gpGoInactive *InactiveInfo)
  672. {
  673.     TabInfo            *Info = INST_DATA(class,gadget);
  674.     struct RastPort    *RPort;
  675.     LONG             Index;
  676.  
  677.     if(InactiveInfo->gpgi_Abort)
  678.         Index = Info->Initial;
  679.     else
  680.         Index = Info->Current;
  681.  
  682.     if(RPort = ObtainGIRPort(InactiveInfo->gpgi_GInfo))
  683.     {
  684.         Info->Current = Index;
  685.  
  686.         DoMethod((Object *)gadget,GM_RENDER,InactiveInfo->gpgi_GInfo,RPort,GREDRAW_REDRAW);
  687.  
  688.         ReleaseGIRPort(RPort);
  689.     }
  690.  
  691.     return(0);
  692. }
  693.  
  694. BOOL
  695. LTP_ObtainTabSize(struct IBox *Box,...)
  696. {
  697.     va_list             VarArgs;
  698.     struct TagItem    *TagList,*Tag;
  699.     struct TextAttr    *FontAttr;
  700.     struct DrawInfo    *DrawInfo;
  701.     STRPTR            *Labels;
  702.     LONG             Count;
  703.     LONG             SizeType;
  704.     BOOL             Success;
  705.  
  706.     Success = FALSE;
  707.  
  708.     va_start(VarArgs,Box);
  709.  
  710.     TagList = (struct TagItem *)VarArgs;
  711.  
  712.     SizeType = GDOMAIN_NOMINAL;
  713.     FontAttr = NULL;
  714.     DrawInfo = NULL;
  715.     Labels = NULL;
  716.  
  717.     while(Tag = NextTagItem(&TagList))
  718.     {
  719.         switch(Tag->ti_Tag)
  720.         {
  721.             case TIA_Labels:
  722.                 Labels = (STRPTR *)Tag->ti_Data;
  723.                 break;
  724.  
  725.             case TIA_Font:
  726.                 FontAttr = (struct TextAttr *)Tag->ti_Data;
  727.                 break;
  728.  
  729.             case TIA_DrawInfo:
  730.                 DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  731.                 break;
  732.  
  733.             case TIA_SizeType:
  734.                 SizeType = Tag->ti_Data;
  735.                 break;
  736.         }
  737.     }
  738.  
  739.     Count = 0;
  740.  
  741.     if(Labels)
  742.     {
  743.         while(Labels[Count])
  744.             Count++;
  745.     }
  746.  
  747.     if(DrawInfo && FontAttr && Labels && Count)
  748.     {
  749.         struct TextFont *Font;
  750.  
  751.         if(Font = OpenFont(FontAttr))
  752.         {
  753.             struct RastPort    RastPort,*RPort = &RastPort;
  754.             LONG            i,Len,MaxWidth;
  755.             LONG            Lean,Thick;
  756.  
  757.             InitRastPort(RPort);
  758.  
  759.             SetFont(RPort,Font);
  760.  
  761.             Box->Left    = 0;
  762.             Box->Top    = 0;
  763.             Box->Height    = RPort->TxHeight + 11;
  764.  
  765.             Lean = (TextLength(RPort,"O",1) + 1) / 2;
  766.  
  767.             Thick = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
  768.  
  769.             if(Thick < 1)
  770.                 Thick = 1;
  771.  
  772.             for(i = MaxWidth = 0 ; i < Count ; i++)
  773.             {
  774.                 if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  775.                     MaxWidth = Len;
  776.             }
  777.  
  778.             MaxWidth = 2 + (Lean + Thick - 1 + Thick + MaxWidth + Thick + Lean + Thick - 1) + 2;
  779.  
  780.             if(SizeType == GDOMAIN_MINIMUM && Count > 1)
  781.                 Box->Width = 2 * Thick + MaxWidth + (Count - 1) * (Thick * 4) + Thick * 3;
  782.             else
  783.                 Box->Width = 2 * Thick + Count * (MaxWidth + Thick) + Thick * 2;
  784.  
  785.             CloseFont(Font);
  786.  
  787.             Success = TRUE;
  788.         }
  789.     }
  790.  
  791.     va_end(VarArgs);
  792.  
  793.     return(Success);
  794. }
  795.  
  796. ULONG SAVE_DS ASM
  797. LTP_TabClassDispatcher(REG(a0) struct IClass *class,REG(a2) Object *object,REG(a1) Msg msg)
  798. {
  799.     switch(msg->MethodID)
  800.     {
  801.         case OM_NEW:
  802.             return(NewMethod(class,(struct Gadget *)object,(struct opSet *)msg));
  803.  
  804.         case OM_UPDATE:
  805.         case OM_SET:
  806.             SetMethod(class,(struct Gadget *)object,(struct opSet *)msg);
  807.             break;
  808.  
  809.         case GM_RENDER:
  810.             return(RenderMethod(class,(struct Gadget *)object,(struct gpRender *)msg));
  811.  
  812.         case GM_HITTEST:
  813.             return(GMR_GADGETHIT);
  814.  
  815.         case GM_GOINACTIVE:
  816.             return(InactiveMethod(class,(struct Gadget *)object,(struct gpGoInactive *)msg));
  817.  
  818.         case GM_HANDLEINPUT:
  819.             return(InputMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  820.  
  821.         case GM_GOACTIVE:
  822.             return(ActiveMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  823.  
  824.         case OM_DISPOSE:
  825.             DisposeMethod(class,(struct Gadget *)object,msg);
  826.  
  827.             // Falls down through to the default case...
  828.     }
  829.  
  830.     return(DoSuperMethodA(class,object,msg));
  831. }
  832.  
  833. #endif    // defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  834.